package com.e0box.game.utils
{
	import com.e0box.game.logicGraphics.Options;
	
	import utils.ObjectArray;

	public class Language
	{
		public static const LANGUAGE_EN:String = "en";
		public static const LANGUAGE_ZH_CN:String = "zh-CN";
		public static const LANGUAGE_ZH_TW:String = "zh-TW";
		
		/**
		 * RegExp %content%
		 */		
		private static const REPLACEKEY_MASK:String = "%([\\w\\.]+)%";
		
		private static var _instance:Language;
		
		private var _langs:ObjectArray;
		
		private var _currentLanguage:String;
		private var _currentContent:ObjectArray;
		
		public function Language(single:validate)
		{
			if(!single) throw new Error("Please use the static method 'get instance'.");
			
			init();
		}
		private function init():void{
			_langs = new ObjectArray();
		}
		private function addLang(content:XML):void{
			
			if(_langs.containsKey(content.@lang)){
				Tools.error("language:" + content.@lang + " already setted.");
			}
			
			var contents:ObjectArray = new ObjectArray();
			
			var text:XML;
			
			
			var t:String;
			var reg:RegExp = /\\n/g;
			if(Options.DEBUG){
				for each(text in content.children()){
					if(contents.containsKey(text.@id)){
						Tools.echo("repeat text id:" + text.@id);
					}
					t = String(text);
					t = t.replace(reg,"\n");
					contents.put(text.@id,t);
				}
			}else{
				for each(text in content.children()){
					t = String(text);
					t = t.replace(reg,"\n");
					contents.put(text.@id,t);
				}
			}
			
			_langs.put(content.@lang, contents);
			
			if(!_currentLanguage){
				changeLanguage(content.@lang);
			}
			
			if(Options.DEBUG){
				Tools.echo("Language:" + content.@lang + " set completed.");
			}
			
		}
		
		/**
		 * add language data
		 * @param lang
		 * 
		 */		
		public function setLanguage(lang:XML):void{
			
			for each(var contents:XML in lang.children()){
				addLang(contents);
			}
			
		}
		
		/**
		 * delete language data with lang
		 * @param lang
		 * 
		 */		
		public function deleteLanguage(lang:String):void{
			if(_langs.containsKey(lang)){
				var con:ObjectArray = _langs.getValueByKey(lang) as ObjectArray;
				con.clear();
				_langs.removeByKey(lang);
				
				if(_currentLanguage == lang){
					_currentLanguage = getLanguageIds()[0];
					if(_currentLanguage){
						changeLanguage(_currentLanguage);
					}else{
						_currentContent = null;
					}
				}
			}else{
				Tools.error("There is no language:" + lang + " data to delete.");
			}
		}
		
		/**
		 * change current language with lang
		 * @param lang
		 * 
		 */		
		public function changeLanguage(lang:String):void{
			if(_langs.containsKey(lang)){
				_currentLanguage = lang;
				_currentContent = _langs.getValueByKey(lang) as ObjectArray;
				
			}else{
				Tools.error("There is no language:" + lang + " data to change.");
			}
		}
		
		/**
		 * current language lang
		 * @return 
		 * 
		 */		
		public function get currentLanguage():String{
			return _currentLanguage;
		}
		
		/**
		 * get text from current language by id
		 * @param id
		 * @return 
		 * 
		 */		
		public function getText(id:String):String{
			if(isContains(id))
				return _currentContent.getValueByKey(id) as String;
			else
				return id;
		}
		
		/**
		 * check id is enabled
		 * @param id
		 * @return 
		 * 
		 */		
		public function isContains(id:String):Boolean{
			return (_currentContent && _currentContent.containsKey(id));
		}
		
		/**
		 * get text and replace the content from current language by id
		 * @param id
		 * @param replace
		 * @return 
		 * 
		 */		
		public function getAndReplaceText(id:String,replace:Object):String{
			var result:String = getText(id);
			
			var regExp:RegExp = new RegExp(REPLACEKEY_MASK, "g");
			
			result = result.replace(regExp, function(match:String, key:String, index:uint, completeString:String) : String {
				var replacement:String = replace[key];
							
				return replacement != null ? replacement : match; // keep %playerName% in text if replacement wasn't available.
			});
			
			return result;
		}
		
		/**
		 * get all ids in current language
		 * @return 
		 * 
		 */		
		public function getTextIds():Array{
			return _currentContent.getKeys();
		}
		
		/**
		 * get all langs
		 * @return 
		 * 
		 */		
		public function getLanguageIds():Array{
			return _langs.getKeys();
		}
		
		
		public static function get instance():Language{
			if(!_instance) _instance = new Language(new validate());
			
			return _instance;
		}
	}
}
class validate{
	public function validate(){
		
	}
}